const express = require('express');
const cors = require('cors');
const fs = require('fs-extra');
const path = require('path');
const glob = require('glob');

const app = express();
const PORT = 3000;

// 中间件
app.use(cors());
app.use(express.json());
app.use(express.static('public'));

// 存储依赖关系数据
let dependencyGraph = {
    nodes: [],
    edges: []
};

// 存储所有JSON文件的name映射
let nameToFileMap = new Map();

/**
 * 扫描metadata目录中的所有JSON文件
 */
async function scanJsonFiles() {
    const metadataPath = path.join(__dirname, '..', 'metadata');
    const jsonFiles = glob.sync('**/*.json', { cwd: metadataPath });
    
    console.log(`找到 ${jsonFiles.length} 个JSON文件`);
    
    const fileData = [];
    
    for (const file of jsonFiles) {
        try {
            const filePath = path.join(metadataPath, file);
            const content = await fs.readJson(filePath);
            
            if (content.name) {
                nameToFileMap.set(content.name, file);
                fileData.push({
                    file: file,
                    name: content.name,
                    title: content.title || '',
                    dependencies: content.dependencies || [],
                    category: content.category || 'unknown',
                    define: content.define || ''
                });
            }
        } catch (error) {
            console.warn(`解析文件失败: ${file}`, error.message);
        }
    }
    
    return fileData;
}

/**
 * 构建依赖关系图
 */
function buildDependencyGraph(fileData) {
    const nodes = [];
    const edges = [];
    const nodeMap = new Map();
    const seenNodes = new Set();
    const seenEdges = new Set();
    
    // 创建节点 - 去重处理
    fileData.forEach((file, index) => {
        if (!seenNodes.has(file.name)) {
            seenNodes.add(file.name);
            const node = {
                id: file.name,
                label: file.title || file.name,
                file: file.file,
                category: file.category,
                define: file.define,
                dependencies: file.dependencies,
                group: getCategoryGroup(file.category)
            };
            
            nodes.push(node);
            nodeMap.set(file.name, node);
        }
    });
    
    // 创建边（依赖关系）- 去重处理
    fileData.forEach(file => {
        if (file.dependencies && file.dependencies.length > 0) {
            file.dependencies.forEach(dep => {
                // 检查依赖是否存在对应的文件
                if (nameToFileMap.has(dep)) {
                    const edgeKey = `${file.name}-${dep}`;
                    if (!seenEdges.has(edgeKey)) {
                        seenEdges.add(edgeKey);
                        const edge = {
                            from: file.name,
                            to: dep,
                            label: 'depends on',
                            arrows: 'to'
                        };
                        edges.push(edge);
                    }
                }
            });
        }
    });
    
    return { nodes, edges };
}

/**
 * 根据category获取分组
 */
function getCategoryGroup(category) {
    const categoryGroups = {
        'bill': 1,
        'datamodel': 2,
        'approve': 3,
        'basedata': 4,
        'querysource': 5,
        'queryview': 6,
        'print': 7,
        'invoice': 8,
        'message': 9,
        'workflowQuery': 10
    };
    
    return categoryGroups[category] || 0;
}

/**
 * 获取依赖关系数据
 */
app.get('/api/dependencies', async (req, res) => {
    try {
        if (dependencyGraph.nodes.length === 0) {
            const fileData = await scanJsonFiles();
            dependencyGraph = buildDependencyGraph(fileData);
        }
        
        res.json(dependencyGraph);
    } catch (error) {
        console.error('获取依赖关系失败:', error);
        res.status(500).json({ error: '获取依赖关系失败' });
    }
});

/**
 * 搜索节点
 */
app.get('/api/search', async (req, res) => {
    try {
        const query = req.query.q;
        if (!query) {
            return res.json([]);
        }
        
        const results = dependencyGraph.nodes.filter(node => 
            node.label.toLowerCase().includes(query.toLowerCase()) ||
            node.id.toLowerCase().includes(query.toLowerCase()) ||
            node.file.toLowerCase().includes(query.toLowerCase())
        );
        
        res.json(results);
    } catch (error) {
        console.error('搜索失败:', error);
        res.status(500).json({ error: '搜索失败' });
    }
});

/**
 * 获取节点详情
 */
app.get('/api/node/:id', async (req, res) => {
    try {
        const nodeId = req.params.id;
        const node = dependencyGraph.nodes.find(n => n.id === nodeId);
        
        if (!node) {
            return res.status(404).json({ error: '节点不存在' });
        }
        
        // 获取依赖此节点的其他节点
        const dependents = dependencyGraph.edges
            .filter(edge => edge.to === nodeId)
            .map(edge => dependencyGraph.nodes.find(n => n.id === edge.from))
            .filter(Boolean);
        
        // 获取此节点依赖的节点
        const dependencies = dependencyGraph.edges
            .filter(edge => edge.from === nodeId)
            .map(edge => dependencyGraph.nodes.find(n => n.id === edge.to))
            .filter(Boolean);
        
        res.json({
            ...node,
            dependents,
            dependencies
        });
    } catch (error) {
        console.error('获取节点详情失败:', error);
        res.status(500).json({ error: '获取节点详情失败' });
    }
});

/**
 * 重新扫描文件
 */
app.post('/api/rescan', async (req, res) => {
    try {
        dependencyGraph = { nodes: [], edges: [] };
        nameToFileMap.clear();
        
        const fileData = await scanJsonFiles();
        dependencyGraph = buildDependencyGraph(fileData);
        
        res.json({ message: '重新扫描完成', count: dependencyGraph.nodes.length });
    } catch (error) {
        console.error('重新扫描失败:', error);
        res.status(500).json({ error: '重新扫描失败' });
    }
});

// 启动服务器
app.listen(PORT, () => {
    console.log(`服务器运行在 http://localhost:${PORT}`);
    console.log('正在扫描metadata目录...');
    
    // 启动时自动扫描
    scanJsonFiles().then(fileData => {
        dependencyGraph = buildDependencyGraph(fileData);
        console.log(`扫描完成，找到 ${dependencyGraph.nodes.length} 个节点，${dependencyGraph.edges.length} 条依赖关系`);
    }).catch(error => {
        console.error('初始扫描失败:', error);
    });
});
